var date_inf = new Date();
date_inf.setFullYear(date_inf.getFullYear() + 5);
var DATE_INF = parseInt(date_inf.getTime() / 1000, 10);

function date_euro_to_unix_format(input) {
    // Assuming 6/12/2012 => 6-12-2012
    date_array = explode('/', input);
    return (is_array(date_array) && count(date_array) == 3) ? date_array[0] + '-' + date_array[1] + '-' + date_array[2] : '1-1-1970';
}

function date_euro_to_utimestamp(input) {
    // Assuming 6/12/2012 => 126584848800
    date_array = explode('/', input);
    var us_format = date_array[1] + '/' + date_array[0] + '/' + date_array[2]
    return new Date(us_format).getTime() / 1000;
}

function next_month(time) {
    var now = new Date(time * 1000);
    if (now.getMonth() == 11) {
        current = new Date(now.getFullYear() + 1, 0, now.getDate(), now.getHours(), now.getMinutes());
    } else {
        current = new Date(now.getFullYear(), now.getMonth() + 1, now.getDate(), now.getHours(), now.getMinutes());
    }
    if (isNaN(current.getTime())) {
        return DATE_INF;
    }
    return current.getTime() / 1000;
}

function next_year(time) {
    var now = new Date(time * 1000);
    return new Date(now.getFullYear() + 1, now.getMonth(), now.getDate(), now.getHours(), now.getMinutes()) / 1000;
}



function find_serie_deletion_starter(input) {
    minor = -1;
    if (is_array(input)) {
        for (var key in input) {
            value = input[key];
            if (value == 'n') {
                minor = (minor == -1 || minor > input[key - 1]) ? input[key - 1] : minor;
            }
        }
    }
    return minor;
}


function array_filter_numeric(input) {
    result = new Array();
    if (is_array(input)) {
        for (var key in input) {
            value = input[key];
            if (is_numeric(value)) {
                result[key] = value;
            }
        }
    }
    return result;
}


function filter_array(input) {
    var result = new Array();
    if (is_array(input)) {
        for (var key in input) {
            value = input[key];
            if (input[key] != '') {
                result[key] = value;
            }
        }
    }
    return input;
}

function is_between(item, start, end, duration) {
    if (duration == undefined) {
        return (item >= start && item <= end) ? true : false;
    }
    return (item >= start && item + duration <= end) ? true : false;
}

function getMonday(d) {
    d = new Date(d);
    var day = d.getDay(),
            diff = d.getDate() - day + (day == 0 ? -6 : 1); // adjust when day is sunday
    return new Date(d.setDate(diff));
}


function _index_to_time(dayString, weekIndex, time) {
    list = {
        'monday': 0,
        'tuesday': 1,
        'wednesday': 2,
        'thursday': 3,
        'friday': 4,
        'saturday': 5,
        'sunday': 6
    };
    dayPadding = (3600 * 24) * list[dayString];
    weekPadding = (3600 * 24 * 7) * weekIndex;
    slot_monday = getMonday(time * 1000).getTime() / 1000;

    padding = dayPadding + weekPadding;
    return slot_monday + padding;
}

function getSlotDay(dateTime) {
    var d = new Date(dateTime * 1000);
    return d.setHours(0, 0, 0, 0) / 1000;
}

function getSlotTime(dateTime) {
    return (dateTime) - (getSlotDay(dateTime));
}

function enable_repeat(event, event_list, agendaIdArrayFlipped, startCalendar, endCalendar, webView, forJavascript) {
    // Function source is PHP
    startCalendar = startCalendar / 1000;
    endCalendar = endCalendar / 1000;
    eventStart = (event.slot_start + event.slot_day);
    eventEnd = (event.slot_end + event.slot_day);
    eventLength = eventEnd - eventStart;
    userId = isset(agendaIdArrayFlipped[event.agenda_id]) ? parseInt(agendaIdArrayFlipped[event.agenda_id], 10) : '';
    // Get deleted occurencies and set back array to numeric values ony
    deleted_occurencies = strlen(event.deleted_occurencies) ? filter_array(explode(';', event.deleted_occurencies)) : new Array();
    serie_deletion_start = find_serie_deletion_starter(deleted_occurencies);
    deleted_occurencies = array_filter_numeric(deleted_occurencies);
    // Check if event belongs to current interval
    if (is_between(eventStart, startCalendar, endCalendar) || is_between(eventEnd, startCalendar, endCalendar)) {
        if (forJavascript == true) {
            current_slot = {
                'id': event.id,
                'agenda_id': event.agenda_id,
                'start': eventStart * 1000,
                'end': eventEnd * 1000,
                'realStart': eventStart * 1000,
                'slot_day': event.slot_day,
                'slot_start': event.slot_start,
                'slot_end': event.slot_end,
                'title': event.title,
                'userId': userId,
                'occurency': 'original',
                'event_type': event.event_type,
                'color': event.color,
                'repeat_enabled': event.repeat_enabled,
                'repeat_time': event.repeat_time,
                'repeat_period': event.repeat_period,
                'repeat_occurency': event.repeat_occurency,
                'repeat_occurency_date': event.repeat_occurency_date,
                'repeat_on_specific_days': event.repeat_on_specific_days,
                'content': event.content,
                'deleted_occurencies': event.deleted_occurencies,
                'prestation': event.prestation,
                'prestation_specific': event.prestation_specific
            };
        } else {
            current_slot = {
                'start': eventStart,
                'end': eventEnd
            };
        }
        if (webView == false) {
            current_slot['free'] = false;
        }
        event_list.push(current_slot);
    }
    // If event is a slot and repeated, calculate limits
    if (event.repeat_enabled == 'repeat' && (event.event_type == 'slot' || event.event_type == 'web')) {
        limit_sup = DATE_INF; // IF repeat_occurency == 'always
        if (event.repeat_occurency == 'specific_date') {
            limit_sup = date_euro_to_utimestamp(event.repeat_occurency_date);
        }
        if (event.repeat_occurency == 'while') {
            // FIXME : calculate step depending repeat_period
            if (event.repeat_period == 'jour') {
                step_length = (3600 * 24);
            }
            if (event.repeat_period == 'semaine') {
                step_length = (3600 * 24 * 7);
            }
            if (event.repeat_period == 'mois') {
                step_length = (3600 * 24 * 31);
            }
            if (event.repeat_period == 'an') {
                step_length = (3600 * 24 * 365);
            }
            limit_sup = (step_length) + eventStart;
        }
        // IF event MAY be in our calendar...
        if (limit_sup > startCalendar && eventStart < endCalendar) {
            ///////////////////////////
            // REPEAT PERIOD = JOUR
            ///////////////////////////
            if (event.repeat_period == 'jour') {
                // Event is always repeated
                ///////////////////////////
                // Define end of calculation
                if (event.repeat_occurency == 'always') {
                    endEventDisplay = endCalendar;
                } else if (event.repeat_occurency == 'specific_date') {
                    endEventDisplay = date_euro_to_utimestamp(event.repeat_occurency_date);
                    endEventDisplay = (endEventDisplay > endCalendar) ? endCalendar : endEventDisplay; // Saves computing time
                }

                step_length = (3600 * 24) * event.repeat_time; // repeat_time = "1 jour", "2 jours" ... "n jours"
                repeatStart = eventStart + step_length;
                repeatEnd = repeatStart + eventLength;
                occurency = 0;
                while (repeatStart <= endEventDisplay) {
                    if (is_between(repeatStart, startCalendar, endEventDisplay) || is_between(repeatEnd, startCalendar, endEventDisplay)) {
                        if (!in_array(occurency, deleted_occurencies) &&
                                !(serie_deletion_start > -1 && serie_deletion_start < occurency)) {
                            if (forJavascript == true) {
                                repeat_slot = {
                                    'id': event.id,
                                    'agenda_id': event.agenda_id,
                                    'start': repeatStart * 1000,
                                    'end': repeatEnd * 1000,
                                    'slot_day': getSlotDay(repeatStart),
                                    'slot_start': getSlotTime(repeatStart),
                                    'slot_end': getSlotTime(repeatEnd),
                                    'realStart': eventStart * 1000,
                                    'title': event.title,
                                    'userId': userId,
                                    'occurency': occurency,
                                    'event_type': event.event_type,
                                    'color': event.color,
                                    'repeat_enabled': event.repeat_enabled,
                                    'repeat_time': event.repeat_time,
                                    'repeat_period': event.repeat_period,
                                    'repeat_occurency': event.repeat_occurency,
                                    'repeat_occurency_date': event.repeat_occurency_date,
                                    'repeat_on_specific_days': event.repeat_on_specific_days,
                                    'content': event.content,
                                    'deleted_occurencies': event.deleted_occurencies,
                                    'prestation': event.prestation,
                                    'prestation_specific': event.prestation_specific
                                };
                            } else {
                                repeat_slot = {
                                    'start': repeatStart,
                                    'end': repeatEnd
                                };
                            }
                            if (webView == false) {
                                repeat_slot['free'] = false;
                            }
                            event_list.push(repeat_slot);
                        }
                    }
                    repeatStart += step_length;
                    repeatEnd = repeatStart + eventLength;
                    occurency++;
                }
            }
            ///////////////////////////
            // REPEAT PERIOD = SEMAINE
            ///////////////////////////
            if (event.repeat_period == 'semaine') {
                if (event.repeat_occurency == 'always') {
                    endEventDisplay = endCalendar;
                } else if (event.repeat_occurency == 'specific_date') {
                    endEventDisplay = date_euro_to_utimestamp(event.repeat_occurency_date);
                    endEventDisplay = (endEventDisplay > endCalendar) ? endCalendar : endEventDisplay; // Saves computing time
                }
                day_list = strlen(event.repeat_on_specific_days) ? explode('§', event.repeat_on_specific_days) : new Array();
                if (count(day_list)) {
                    repeatStart = (event.slot_day + event.slot_start);
                    repeatEnd = repeatStart + eventLength;
                    occurency = 0;
                    indexWeek = 0;
                    while (repeatStart <= endEventDisplay) {
                        if (!(indexWeek % event.repeat_time)) {
                            for (i = 0; i < count(day_list); i++) {
                                repeatStart = (_index_to_time(day_list[i], indexWeek, startCalendar) + event.slot_start);
                                repeatEnd = repeatStart + eventLength;
                                if (repeatStart > eventStart && (is_between(repeatStart, startCalendar, endEventDisplay) || is_between(repeatEnd, startCalendar, endEventDisplay))) {
                                    if (!count(deleted_occurencies) || !in_array(occurency, deleted_occurencies)) {
                                        if (forJavascript == true) {
                                            repeat_slot = {
                                                'id': event.id,
                                                'agenda_id': event.agenda_id,
                                                'start': repeatStart * 1000,
                                                'end': repeatEnd * 1000,
                                                'slot_day': getSlotDay(repeatStart),
                                                'slot_start': getSlotTime(repeatStart),
                                                'slot_end': getSlotTime(repeatEnd),
                                                'realStart': eventStart * 1000,
                                                'title': event.title,
                                                'userId': userId,
                                                'occurency': occurency,
                                                'event_type': event.event_type,
                                                'color': event.color,
                                                'repeat_enabled': event.repeat_enabled,
                                                'repeat_time': event.repeat_time,
                                                'repeat_period': event.repeat_period,
                                                'repeat_occurency': event.repeat_occurency,
                                                'repeat_occurency_date': event.repeat_occurency_date,
                                                'repeat_on_specific_days': event.repeat_on_specific_days,
                                                'content': event.content,
                                                'deleted_occurencies': event.deleted_occurencies,
                                                'prestation': event.prestation,
                                                'prestation_specific': event.prestation_specific
                                            };
                                        } else {
                                            repeat_slot = {
                                                'start': repeatStart,
                                                'end': repeatEnd
                                            };
                                        }
                                        if (webView == false) {
                                            repeat_slot['free'] = false;
                                        }
                                        event_list.push(repeat_slot);
                                    }
                                }
                                occurency++;
                            }
                        }
                        indexWeek++;
                        repeatStart = (_index_to_time(day_list[0], indexWeek, event.slot_day) + event.slot_start);
                        repeatEnd = repeatStart + eventLength;
                    }
                }
            }
            ////////////////////////////////
            // REPEAT PERIOD = MOIS OU AN
            ///////////////////////////////
            if (event.repeat_period == 'mois' || event.repeat_period == 'an') {
                // Event is always repeated
                ///////////////////////////
                // Define end of calculation
                if (event.repeat_occurency == 'always') {
                    endEventDisplay = endCalendar;
                } else if (event.repeat_occurency == 'specific_date') {
                    endEventDisplay = date_euro_to_utimestamp(event.repeat_occurency_date);
                    endEventDisplay = (endEventDisplay > endCalendar) ? endCalendar : endEventDisplay; // Saves computing time
                }

                var eventDate = new Date((event.slot_start + event.slot_day) * 1000);
                repeatStart = eventDate.getTime() / 1000;
                repeatEnd = repeatStart + eventLength;
                occurency = 0;
                indexTime = -1;
                while (repeatStart <= endEventDisplay) {
                    if (!(indexTime % event.repeat_time)) {
                        if (repeatStart > eventStart && (is_between(repeatStart, startCalendar, endEventDisplay) || is_between(repeatEnd, startCalendar, endEventDisplay))) {
                            if (!in_array(occurency, deleted_occurencies)) {
                                if (forJavascript == true) {
                                    repeat_slot = {
                                        'id': event.id,
                                        'agenda_id': event.agenda_id,
                                        'start': repeatStart * 1000,
                                        'end': repeatEnd * 1000,
                                        'slot_day': getSlotDay(repeatStart),
                                        'slot_start': getSlotTime(repeatStart),
                                        'slot_end': getSlotTime(repeatEnd),
                                        'realStart': eventStart * 1000,
                                        'title': event.title,
                                        'userId': userId,
                                        'occurency': occurency,
                                        'event_type': event.event_type,
                                        'color': event.color,
                                        'repeat_enabled': event.repeat_enabled,
                                        'repeat_time': event.repeat_time,
                                        'repeat_period': event.repeat_period,
                                        'repeat_occurency': event.repeat_occurency,
                                        'repeat_occurency_date': event.repeat_occurency_date,
                                        'repeat_on_specific_days': event.repeat_on_specific_days,
                                        'content': event.content,
                                        'deleted_occurencies': event.deleted_occurencies,
                                        'prestation': event.prestation,
                                        'prestation_specific': event.prestation_specific
                                    };
                                } else {
                                    repeat_slot = {
                                        'start': repeatStart,
                                        'end': repeatEnd
                                    };
                                }
                                if (webView == false) {
                                    repeat_slot['free'] = false;
                                }
                                event_list.push(repeat_slot);
                            }
                        }
                    }
                    occurency++;
                    indexTime++;
                    if (event.repeat_period == 'mois') {
                        repeatStart = next_month(repeatStart);
                    } else {
                        repeatStart = next_year(repeatStart);
                    }
                    repeatEnd = repeatStart + eventLength;
                }
            }
        }
    }
    return event_list;
}